using System.Collections;
using System.Collections.Generic;
using EnvDTE;

namespace VSSDKAssist.Assets.Helpers
{
	/// <summary>
	/// Iterator for ProjectItems
	/// </summary>
	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
	public class ProjectItemIterator : IEnumerable<ProjectItem>
	{
		#region Fields
		private Project project;
		private ProjectItem projectItem;
		#endregion

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="ProjectItemIterator"/> class.
		/// </summary>
		/// <param name="project">The project.</param>
		public ProjectItemIterator(Project project)
		{
			Guard.ArgumentNotNull(project, "project");
			this.project = project;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ProjectItemIterator"/> class.
		/// </summary>
		/// <param name="projectItem">The project item.</param>
		public ProjectItemIterator(ProjectItem projectItem)
		{
			Guard.ArgumentNotNull(projectItem, "projectItem");
			this.projectItem = projectItem;
		} 
		#endregion

		#region IEnumerable<ProjectItem> Members
		/// <summary>
		/// Returns an enumerator that iterates through the collection.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> that can be used to iterate through the collection.
		/// </returns>
		public IEnumerator<ProjectItem> GetEnumerator()
		{
			if(project != null)
			{
				foreach(ProjectItem item in project.ProjectItems)
				{
					yield return item;
					foreach(ProjectItem subItem in EnumerateProjectItem(item))
					{
						yield return subItem;
					}
				}
			}
			else if(projectItem != null)
			{
				foreach(ProjectItem subItem in EnumerateProjectItem(projectItem))
				{
					yield return subItem;
				}
			}
			else
			{
				yield break;
			}
		}
		#endregion

		#region Private Implementation
		private IEnumerable<ProjectItem> EnumerateProjectItem(ProjectItem item)
		{
			if(item.ProjectItems == null)
			{
				yield break;
			}

			foreach(ProjectItem subItem in item.ProjectItems)
			{
				yield return subItem;
				foreach(ProjectItem subSubItem in EnumerateProjectItem(subItem))
				{
					yield return subSubItem;
				}
			}
		}
		#endregion

		#region IEnumerable Members
		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		#endregion
	}
}